﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Wydatki.Init;

namespace Wydatki.Tools.Lotto
{
    public static class ActionLottNames
    {
        public const string ZZakresu = "Z Zakresu";
        public const string Parzyste = "Parzyste";
        public const string NieParzyste = "Nieparzyste";
        public const string Kolejne = "Kolejne";
        public const string PseudoKolejne = "PseudoKolejne";
        public const string WiekszeO = "WiększeO";
    }

    public abstract class ActionLottoBase
    {
        public virtual bool IsActionForLosowanie
        {
            get { return false; }
        }

        protected const string STP_COL_REFIX = "STP_LSG_";
        protected const string WRK_COL_REFIX = "WRK_LSL_";
        protected const string WRK_COL_WYBOR_REFIX = "WRK_LWK_";
        private string Prefix;

        public abstract string Name { get; }
        public abstract string Kod { get; }
        public abstract string Opis { get; }

        public abstract bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z);
        
        protected object GetColval(DataRow r, string XYZ)
        {
            object obj = null;
            obj = r[Prefix + XYZ];
            return obj;
        }

        protected void SetColError(DataRow r, string XYZ, string error)
        {
            r.SetColumnError(Prefix + XYZ, error);
        }

        protected abstract string EditableColumns
        {
            get;
        }
        public virtual bool IsColReadOnly(string XYZ)
        {
            return !EditableColumns.Contains(XYZ);
        }
        public virtual bool IsColRequired(string XYZ)
        {
            return !IsColReadOnly(XYZ);
        }

        public abstract bool ValidateParams(DataRow row);

        public static DataTable GetGlobalLottoTypes()
        {
            DataTable dt = Init.InitForm.GetStaticTable(InitFormBrowserNames.Glowna.LottoTypyStatystykGlobalnych);

            foreach (KeyValuePair<string, ActionLottoBase> kvp in Actions)
            {
                dt.Rows.Add(kvp.Value.Kod, kvp.Value.Name);
            }
            return dt;
        }
        public static DataTable GetLottoTypesForLosowania()
        {
            DataTable dt = Init.InitForm.GetStaticTable(Init.InitFormBrowserNames.Glowna.LottoTypyStatystykLosowan);
            foreach (KeyValuePair<string, ActionLottoBase> kvp in ActionsForLosowania)
            {
                dt.Rows.Add(kvp.Value.Kod, kvp.Value.Name);
            }
            return dt;
        }
        public static DataTable GetLottoTypesForWybor()
        {
            DataTable dt = Init.InitForm.GetStaticTable(Init.InitFormBrowserNames.Glowna.LottoTypStatystykWoboru);
            foreach (KeyValuePair<string, ActionLottoBase> kvp in ActionsForWyborKombinacji)
            {
                dt.Rows.Add(kvp.Value.Kod, kvp.Value.Name);
            }
            return dt;
        }

        private static Dictionary<string, ActionLottoBase> actions = null;
        private static Dictionary<string, ActionLottoBase> Actions
        {
            get
            {
                if (actions == null)
                {
                    actions = new Dictionary<string, ActionLottoBase>();
                    AddAction(actions, new ActionLottoZZakresu());
                    AddAction(actions, new ActionLottoParzyste());
                    AddAction(actions, new ActionLottoNieparzyste());
                    AddAction(actions, new ActionLottoKolejne());
                    AddAction(actions, new ActionLottoPseudoKolejne());
                    AddAction(actions, new ActionLottoWiekszeO());
                    foreach (KeyValuePair<string, ActionLottoBase> kvp in actions)
                        kvp.Value.Prefix = STP_COL_REFIX;
                }
                return actions;
            }
        }

        private static Dictionary<string, ActionLottoBase> actionsLosowania = null;
        private static Dictionary<string, ActionLottoBase> ActionsForLosowania
        {
            get
            {
                if (actionsLosowania == null)
                {
                    actionsLosowania = new Dictionary<string, ActionLottoBase>();
                    AddAction(actionsLosowania, new ActionLottoZZakresu());
                    AddAction(actionsLosowania, new ActionLottoParzyste());
                    AddAction(actionsLosowania, new ActionLottoNieparzyste());
                    AddAction(actionsLosowania, new ActionLottoKolejne());
                    AddAction(actionsLosowania, new ActionLottoPseudoKolejne());
                    AddAction(actionsLosowania, new ActionLottoWiekszeO());

                    AddAction(actionsLosowania, new ActionLottoGrupy2ZZakresu());
                    AddAction(actionsLosowania, new ActionLottoGrupy3ZZakresu());
                    AddAction(actionsLosowania, new ActionLottoLiczbaZPrzedzialu());
                    AddAction(actionsLosowania, new ActionLottoPowtorzone());
                    AddAction(actionsLosowania, new ActionLottoPowtorzoneWPoprzednich());
                    AddAction(actionsLosowania, new ActionLottoSumaPowtorzen());
                    AddAction(actionsLosowania, new ActionLottoDowolnePowtorzoneYrazy());
                    AddAction(actionsLosowania, new ActionLottoPowtorzoneSymetryczne());
                    AddAction(actionsLosowania, new ActionLottoPowtorzoneSymetryczneOgraniczone());

                    AddAction(actionsLosowania, new ActionLottoNajczestsze());
                    AddAction(actionsLosowania, new ActionLottoNajczestsze2());
                    AddAction(actionsLosowania, new ActionLottoNajczestszeDwojki());
                    AddAction(actionsLosowania, new ActionLottoNajczestszeDwojki2());
                    AddAction(actionsLosowania, new ActionLottoNajczestszeTrojki());
                    AddAction(actionsLosowania, new ActionLottoNajczestszeTrojki2());


                    foreach (KeyValuePair<string, ActionLottoBase> kvp in actionsLosowania)
                        kvp.Value.Prefix = WRK_COL_REFIX;
                }
                return actionsLosowania;
            }
        }

        private static Dictionary<string, ActionLottoBase> actionsWybor = null;
        private static Dictionary<string, ActionLottoBase> ActionsForWyborKombinacji
        {
            get
            {
                if (actionsWybor == null)
                {
                    actionsWybor = new Dictionary<string, ActionLottoBase>();
                    AddAction(actionsWybor, new ActionLottoZZakresu());
                    AddAction(actionsWybor, new ActionLottoParzyste());
                    AddAction(actionsWybor, new ActionLottoNieparzyste());
                    AddAction(actionsWybor, new ActionLottoKolejne());
                    AddAction(actionsWybor, new ActionLottoPseudoKolejne());
                    AddAction(actionsWybor, new ActionLottoWiekszeO());

                    AddAction(actionsWybor, new ActionLottoGrupy2ZZakresu());
                    AddAction(actionsWybor, new ActionLottoGrupy3ZZakresu());
                    AddAction(actionsWybor, new ActionLottoLiczbaZPrzedzialu());
                    AddAction(actionsWybor, new ActionLottoPowtorzone());
                    AddAction(actionsWybor, new ActionLottoPowtorzoneWPoprzednich());
                    AddAction(actionsWybor, new ActionLottoSumaPowtorzen());
                    AddAction(actionsWybor, new ActionLottoDowolnePowtorzoneYrazy());
                    AddAction(actionsWybor, new ActionLottoPowtorzoneSymetryczne());
                    AddAction(actionsWybor, new ActionLottoPowtorzoneSymetryczneOgraniczone());

                    AddAction(actionsWybor, new ActionLottoNajczestsze());
                    AddAction(actionsWybor, new ActionLottoNajczestsze2());
                    AddAction(actionsWybor, new ActionLottoNajczestszeDwojki());
                    AddAction(actionsWybor, new ActionLottoNajczestszeDwojki2());
                    AddAction(actionsWybor, new ActionLottoNajczestszeTrojki());
                    AddAction(actionsWybor, new ActionLottoNajczestszeTrojki2());

                    foreach (KeyValuePair<string, ActionLottoBase> kvp in actionsWybor)
                        kvp.Value.Prefix = WRK_COL_WYBOR_REFIX;
                }
                return actionsWybor;
            }
        }

        private static void AddAction(Dictionary<string, ActionLottoBase> actions, ActionLottoBase action)
        {
            actions.Add(action.Kod, action);
        }
        public static ActionLottoBase GetAction(string type)
        {
            ActionLottoBase a = null;
            if (type.IsNotNull() && Actions.ContainsKey(type))
                a = Actions[type];
            return a;
        }
        public static ActionLottoBase GetActionForLosowania(string type)
        {
            ActionLottoBase a = null;
            if (type.IsNotNull() && ActionsForLosowania.ContainsKey(type))
                a = ActionsForLosowania[type];
            return a;
        }
        public static ActionLottoBase GetActionForWyborKombinacji(string type)
        {
            ActionLottoBase a = null;
            if (type.IsNotNull() && ActionsForWyborKombinacji.ContainsKey(type))
                a = ActionsForWyborKombinacji[type];
            return a;
        }

        private static Dictionary<string, List<List<int>>> Symetryczne = new Dictionary<string, List<List<int>>>();
        private static object lockSymetryczne = new object();
        public static void ClearSymetryczne()
        {
            lock (lockSymetryczne)
            {
                Symetryczne.Clear();
            }
        }

        public static List<List<int>> GetSymetryczne(List<int> liczby)
        {
            List<List<int>> symetryczne = new List<List<int>>();
            int l0 = liczby[0];
            int l1 = liczby[1];
            int l2 = liczby[2];
            int l3 = liczby[3];
            int l4 = liczby[4];
            int l5 = liczby[5];
            /*
             * 44
             * 43
             * 42
             * 41
             * 40
             * 39
             * */
            string key = (l1 - l0) + "," + (l2 - l1) + "," + (l3 - l2) + "," + (l4 - l3) + "," + (l5 - l4);
            lock (lockSymetryczne)
            {
                if (Symetryczne.ContainsKey(key))
                    symetryczne = Symetryczne[key];
                else
                {
                    int max = 49 - l5;
                    for (int i = 1; i < l0; i++)
                    {
                        symetryczne.Add(new List<int>(new int[]{
                        l0-i,
                        l1-i,
                        l2-i,
                        l3-i,
                        l4-i,
                        l5-i}));
                    }
                    for (int i = 0; i <= max; i++)
                    {
                        symetryczne.Add(new List<int>(new int[]{
                        l0+i,
                        l1+i,
                        l2+i,
                        l3+i,
                        l4+i,
                        l5+i}));
                    }
                    Symetryczne.Add(key, symetryczne);
                }
            }
            return symetryczne;
        }
    }
    

    public class ActionLottoZZakresu : ActionLottoBase
    {
        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            if (x < 1 || x > 6)
                return false;
            bool result = true;
            switch (x)
            {
                case 6:
                    result= liczby[0] + y > liczby[5];
                    break;
                case 5:
                    result = (liczby[0] + y > liczby[4]) ||
                        (liczby[1] + y > liczby[5]);
                        break;
                case 4:
                    result = (liczby[0] + y > liczby[3]) ||
                        (liczby[1] + y > liczby[4]) ||
                        (liczby[2] + y > liczby[5]);
                        break;
                case 3:
                    result = (liczby[0] + y > liczby[2]) ||
                        (liczby[1] + y > liczby[3]) ||
                        (liczby[2] + y > liczby[4]) ||
                        (liczby[3] + y > liczby[5]);
                        break;
                case 2:
                    result = (liczby[0] + y > liczby[1]) ||
                        (liczby[1] + y > liczby[2]) ||
                        (liczby[2] + y > liczby[3]) ||
                        (liczby[3] + y > liczby[4]) ||
                        (liczby[4] + y > liczby[5]);
                    break;
            }
            return result;
        }
        protected override string EditableColumns
        {
            get { return "XY"; }
        }
        public override string Name
        {
            get { return "Conajmniej X liczb jest z zakresu Y liczb"; }
        }
        public override string Opis
        {
            get { return Name; }
        }
        public override string Kod
        {
            get { return ActionLottNames.ZZakresu; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt();
            int y = GetColval(row, "Y").AsInt();
            string str="";
            if (x < 2 || x > 6)
            {
                str = "X musi byc z zakresu 2 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y > 48)
            {
                str = "Y musi być mniejsze niż 49";
                SetColError(row, "Y", str);
                return false;
            }
            else if (y < x)
            {
                str = "Y musi byc większe od X";
                SetColError(row, "X", str);
                SetColError(row, "Y", str);
                return false;
            }
            return true;
        }
    }
    public class ActionLottoParzyste : ActionLottoBase
    {
        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count=0;
            for (int i=0; i < 6; i++)
            {
                if (liczby[i] % 2 == 0)
                    count++;
            }
            return count >= x;
        }
        protected override string EditableColumns
        {
            get { return "X"; }
        }
        public override string Name
        {
            get { return "Conajmniej X liczb jest parzystych"; }
        }
        public override string Kod
        {
            get { return ActionLottNames.Parzyste; }
        }
        public override string Opis
        {
            get { return Name; }
        }

        public override bool ValidateParams(DataRow row)
        {
            string str = "";
            int x = GetColval(row, "X").AsInt(-1);
            if (x > 6 || x < 1)
            {
                str = "X musi byc z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            return true;
        }
    }
    public class ActionLottoNieparzyste : ActionLottoBase
    {
        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count=0;
            for (int i=0; i < 6; i++)
            {
                if (liczby[i] % 2 != 0)
                    count++;
            }
            return count >= x;
        }
        protected override string EditableColumns
        {
            get { return "X"; }
        }
        public override string Name
        {
            get { return "Conajmniej X liczb jest nieparzystych"; }
        }
        public override string Kod
        {
            get { return ActionLottNames.NieParzyste; }
        }
        public override string Opis
        {
            get { return Name; }
        }
        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            
            string str = "";
            if (x > 6 || x < 1)
            {
                str = "X musi byc z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            return true;
        }
    }
    public class ActionLottoKolejne : ActionLottoBase
    {
        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count = 1;
            for (int i=0; i < 5; i++)
            {
                if (liczby[i] + 1 == liczby[i + 1])
                    count++;
            }
            return count >= x;
        }
        protected override string EditableColumns
        {
            get { return "X"; }
        }

        public override string Name
        {
            get { return "Conajmniej X liczb jest kolejne"; }
        }
        public override string Kod
        {
            get { return ActionLottNames.Kolejne; }
        }
        public override string Opis
        {
            get { return "Conajmniej X liczb jest większe od poprzedniej o 1"; }
        }
        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            
            string str = "";
            if (x > 6 || x < 2)
            {
                str = "X musi byc z zakresu 2 - 6";
                SetColError(row, "X", str);
                return false;
            }
            return true;
        }
    }
    public class ActionLottoPseudoKolejne : ActionLottoBase
    {
        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int roznicaBazowa = liczby[1] - liczby[0];
            int count = 1;
            for (int i=0; i < 5; i++)
            {
                if (liczby[i] + roznicaBazowa == liczby[i + 1])
                {
                    count++;
                    roznicaBazowa++;
                }
                else
                {
                    roznicaBazowa = liczby[i + 1] - liczby[i]+1;
                }
            }
            return count >= x;
        }
        protected override string EditableColumns
        {
            get { return "X"; }
        }
        public override string Name
        {
            get { return "Conajmniej X liczb jest pseudokolejne"; }
        }
        public override string Kod
        {
            get { return ActionLottNames.PseudoKolejne; }
        }
        public override string Opis
        {
            get { return "Różnica między 2 kolejnymi liczbami jest o 1 większ niż różnica między 2 poprzednimi liczbami."; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            
            string str = "";
            if (x > 6 || x < 3)
            {
                str = "X musi byc z zakresu 3 - 6";
                SetColError(row, "X", str);
                return false;
            }
            return true;
        }
    }
    public class ActionLottoWiekszeO : ActionLottoBase
    {
        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            Dictionary<int,int> dic = new Dictionary<int,int>();
            int roznica = 0;
            for (int i=0; i < 5; i++)
            {
                roznica = liczby[i + 1] - liczby[i];
                if (dic.ContainsKey(roznica))
                    dic[roznica]++;
                else
                    dic.Add(roznica, 1);
            }
            foreach (KeyValuePair<int,int> kvp in dic)
                if (kvp.Value >= x-1)
                    return true;
            return false;
        }
        protected override string EditableColumns
        {
            get { return "X"; }
        }
        public override string Name
        {
            get { return "Conajmniej X liczb jest symetryczne"; }
        }
        public override string Kod
        {
            get { return ActionLottNames.WiekszeO; }
        }
        public override string Opis
        {
            get { return "W X przypadkach różnica między 2 kolejnymi liczbami jest taka sama."; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            
            string str = "";
            if (x > 6 || x < 3)
            {
                str = "X musi byc z zakresu 3 - 6";
                SetColError(row, "X", str);
                return false;
            }
            return true;
        }
    }
    
    #region dla losowan
    public class ActionLottoLiczbaZPrzedzialu : ActionLottoBase
    {
        public override string Name
        {
            get { return "Liczba X jest z przedziału Y-Z"; }
        }

        public override string Kod
        {
            get { return "Liczba z przedziału"; }
        }

        public override string Opis
        {
            get { return "X liczba kombinacji jest z przedziału Y - Z"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            if (liczby[x - 1] >= y && liczby[x - 1] <= z)
                return true;
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XYZ"; }
        }
        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);
            

            string str = "";
            if (x < 1 || x > 6)
            {
                str = "X powinno być z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < x || y > 49)
            {
                str = "Y powinno być z zakresu " + x + " - 49";
                SetColError(row, "Y", str);
                return false;
            }
            else if (z < x || z > 49)
            {
                str = "Z powinno być z zakresu " + x + " - 49";
                SetColError(row, "Z", str);
                return false;
            }
            else if (y > z)
            {
                str = "Y nie może byc większe niż Z";
                SetColError(row, "Y", str);
                SetColError(row, "Z", str);
                return false;
            }
            return true;
        }
    }
    public class ActionLottoGrupy2ZZakresu : ActionLottoBase
    {

        public override string Name
        {
            get { return "Grupy 2 kolejnych liczb są z zakresu"; }
        }

        public override string Kod
        {
            get { return "Grupy 2 z zakresu"; }
        }

        public override string Opis
        {
            get { return "Liczby 1 i 2 są z zakresu X liczb, 3 i 4 z zakresu Y liczb a 5 i 6 z zakresu Z liczb"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            if (liczby[1] - liczby[0] <= x &&
                liczby[3] - liczby[2] <= y &&
                liczby[5] - liczby[4] <= z)
                return true;
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XYZ"; }
        }
        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);
            
            string str = "";
            if (x < 2 || x > 49)
            {
                str = "X powinno być z zakresu 2 - 49";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 2 || y > 49)
            {
                str = "Y powinno być z zakresu 2 - 49";
                SetColError(row, "Y", str);
                return false;
            }
            else if (z < 2 || z > 49)
            {
                str = "Z powinno być z zakresu 2 - 49";
                SetColError(row, "Z", str);
                return false;
            }
            return true;
        }
    }
    public class ActionLottoGrupy3ZZakresu : ActionLottoBase
    {
        public override string Name
        {
            get { return "Grupy 3 kolejnych liczb są z zakresu"; }
        }

        public override string Kod
        {
            get { return "Grupy 3 z zakresu"; }
        }

        public override string Opis
        {
            get { return "Liczby 1,2 i 3 są z zakresu X liczb, 4, 5 i 6 z zakresu Y liczb"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            if (liczby[2] - liczby[0] <= x &&
                liczby[5] - liczby[3] <= y)
                return true;
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XY"; }
        }
        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            
            string str = "";
            if (x < 3 || x > 49)
            {
                str = "X powinno być z zakresu 3 - 49";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 3 || y > 49)
            {
                str = "Y powinno być z zakresu 3 - 49";
                SetColError(row, "Y", str);
                return false;
            }
            return true;
        }
    }
    public class ActionLottoPowtorzone : ActionLottoBase
    {
        public override string Name
        {
            get { return "Conajmniej X liczb powtórzyło się w conajmniej Y losowaniach";  }
        }

        public override string Kod
        {
            get { return "Powtorzone"; }
        }

        public override string Opis
        {
            get { return "Conajmniej X liczb powtórzyło się w conajmniej Y losowaniach"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int lCount=0;
            int count = 0;
            int numerLosowania = liczby[6];
            int max = LottoLosowaniaTools.IloscLosowan;
            List<int> losowanie;
            for(int numer=0;numer<max;numer++)
            {
                losowanie = LottoLosowaniaTools.LosowaniaList[numer];
                if (numer == numerLosowania)
                    continue;
                lCount = 0;
                for (int i=0; i < 6; i++)
                {
                    if (liczby.Contains(losowanie[i]))
                        lCount++;
                    if (lCount == x)
                        break;
                }
                if (lCount == x)
                    count++;
                if (count >= y) // = 1 - wybrane losowanie
                    return true;
            }
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XY"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);

            string str = "";
            if (x < 1 || x > 6)
            {
                str = "X powinno być z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscLosowan)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscLosowan;
                SetColError(row, "Y", str);
                return false;
            }
            return true;
        }
        public override bool IsActionForLosowanie
        {
            get
            {
                return true;
            }
        }
    }

    public class ActionLottoPowtorzoneWPoprzednich : ActionLottoBase
    {
        public override string Name
        {
            get { return "Conajmniej X liczb powtórzyło się w conajmniej Y z Z poprzednich losowaniach"; }
        }

        public override string Kod
        {
            get { return "Powtorzone w poprzednich"; }
        }

        public override string Opis
        {
            get { return "Conajmniej X liczb powtórzyło się w conajmniej Y z Z poprzednich losowaniach"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int lCount=0;
            int count = 0;
            int numerLosowania = liczby[6];
            if (numerLosowania < y)
                return false;
            int iStart = numerLosowania-1;
            int iEnd = numerLosowania-z-1;
            if(iEnd<0)
                iEnd = 0;

            List<int> liczbyLosowania = new List<int>();
            
            List<int> liczbyPoprzedniego;

            for (int i= iStart; i >= iEnd; i--)
            {
                liczbyPoprzedniego = LottoLosowaniaTools.LosowaniaList[i];
                lCount = 0;
                for(int k=0;k<6;k++)
                {
                    if (liczbyPoprzedniego.Contains(liczby[k]))
                    {
                        lCount++;
                        if (lCount == x)
                            break;
                    }
                }
                if (lCount == x)
                    count++;
                if (count == y)
                    return true;
            }
            
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XYZ"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (x < 1 || x > 6)
            {
                str = "X powinno być z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if ( y < 1 || y > LottoLosowaniaTools.IloscLosowan)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscLosowan;
                SetColError(row, "Y", str);
                return false;
            }
            else if (z < 1 || z > LottoLosowaniaTools.IloscLosowan)
            {
                str = "Z powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscLosowan;
                SetColError(row, "Z", str);
                return false;
            }
            return true;
        }

        public override bool IsActionForLosowanie
        {
            get
            {
                return true;
            }
        }
    }
    public class ActionLottoSumaPowtorzen : ActionLottoBase
    {
        public override string Name
        {
            get { return "Suma powtórzeń X liczb wynosi conajmniej Y uwzgledniajac Z poprzednich losowaniach"; }
        }

        public override string Kod
        {
            get { return "Suma powtorzen w poprzednich"; }
        }

        public override string Opis
        {
            get { return "Suma powtórzeń dowolnych X liczb wynosi conajmniej Y uwzględnając maksymalnie Z poprzednich losowań"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int numerLosowania = liczby[6];
            
            int iStart = numerLosowania - 1;
            int iEnd = numerLosowania - z - 1;
            if (iEnd < 0)
                iEnd = 0;

            List<int> liczbyLosowania = new List<int>();

            List<int> liczbyPoprzedniego;
            List<int> ilosc = new List<int>();
            for (int i=0; i < 6; i++)
                ilosc.Add(0);
            int max =0;
            for (int i= iStart; i >= iEnd; i--)
            {
                liczbyPoprzedniego = LottoLosowaniaTools.LosowaniaList[i];
                for (int k=0; k < 6; k++)
                {
                    if (liczbyPoprzedniego.Contains(liczby[k]))
                    {
                        ilosc[k]++;
                    }
                }
                max = SprawdzMaxIlosc(ilosc, x);
                if (max >= y)
                    return true;
            }

            return false;
        }
        private int SprawdzMaxIlosc(List<int> ilosc, int x)
        {
            List<int> il = new List<int>(ilosc);
            il.Sort();
            il.Reverse();
            int max = 0;
            for (int i=0; i < x; i++)
                max += il[i];
            return max;
        }
        protected override string EditableColumns
        {
            get { return "XYZ"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (x < 1 || x > 6)
            {
                str = "X powinno być z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1)
            {
                str = "Y powinno być większe nniż 0";
                SetColError(row, "Y", str);
                return false;
            }
            else if (z > LottoLosowaniaTools.IloscLosowan || z < 1)
            {
                str = "Z powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscLosowan;
                SetColError(row, "Z", str);
                return false;
            }
            return true;
        }

        public override bool IsActionForLosowanie
        {
            get
            {
                return true;
            }
        }
    }
    public class ActionLottoDowolnePowtorzoneYrazy : ActionLottoBase
    {
        public override string Name
        {
            get { return "Dowolne X liczb powtórzyło sie przynajmniej Y uwzgledniajac Z poprzednich losowaniach"; }
        }

        public override string Kod
        {
            get { return "Dowolne powtorzenia w poprzednich"; }
        }

        public override string Opis
        {
            get { return "Każda z X liczb powtórzyła się conajmniej Y uwzględnając maksymalnie Z poprzednich losowań"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int numerLosowania = liczby[6];

            int iStart = numerLosowania - 1;
            int iEnd = numerLosowania - z - 1;
            if (iEnd < 0)
                iEnd = 0;

            List<int> liczbyLosowania = new List<int>();

            List<int> liczbyPoprzedniego;
            List<int> ilosc = new List<int>();
            for (int i=0; i < 6; i++)
                ilosc.Add(0);
            int max =0;
            for (int i= iStart; i >= iEnd; i--)
            {
                max = 0;
                liczbyPoprzedniego = LottoLosowaniaTools.LosowaniaList[i];
                for (int k=0; k < 6; k++)
                {
                    if (liczbyPoprzedniego.Contains(liczby[k]))
                    {
                        ilosc[k]++;
                    }
                }
                for (int k=0; k < 6; k++)
                {
                    if (ilosc[k] >= y)
                        max++;
                }

                if (max >= x)
                    return true;
            }

            return false;
        }
        private int SprawdzMaxIlosc(List<int> ilosc, int x)
        {
            List<int> il = new List<int>(ilosc);
            il.Sort();
            int max = 0;
            for (int i=0; i < x; i++)
                max += il[i];
            return max;
        }
        protected override string EditableColumns
        {
            get { return "XYZ"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (x < 1 || x > 6)
            {
                str = "X powinno być z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1)
            {
                str = "Y powinno być większe nniż 0";
                SetColError(row, "Y", str);
                return false;
            }
            else if (z > LottoLosowaniaTools.IloscLosowan || z < 1)
            {
                str = "Z powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscLosowan;
                SetColError(row, "Z", str);
                return false;
            }
            return true;
        }

        public override bool IsActionForLosowanie
        {
            get
            {
                return true;
            }
        }
    }

    public class ActionLottoPowtorzoneSymetryczne : ActionLottoBase
    {
        public override string Name
        {
            get { return "Conajmniej X liczb lub liczb symetrycznych powtórzyło się w conajmniej Y losowaniach"; }
        }

        public override string Kod
        {
            get { return "Powtorzone symetryczne"; }
        }

        public override string Opis
        {
            get { return "Conajmniej X liczb lub liczb symetrycznych powtórzyło się w conajmniej Y losowaniach"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int lCount = 0;
            int count = 0;

            int numerLosowania = liczby[6];
            if (numerLosowania < y)
                return false;

            int iMin = numerLosowania - z;
            if (iMin < 0)
                iMin = 0;
            List<List<int>> symetryczne = GetSymetryczne(liczby);

            int maxGlobalne = LottoLosowaniaTools.IloscLosowan;
            int maxSymetryczne = symetryczne.Count;


            List<int> losowanieSymetryczne;
            List<int> losowanieGlobalne;
            for (int iGlobalne = iMin; iGlobalne < maxGlobalne; iGlobalne++)
            {
                if (iGlobalne == numerLosowania)
                    continue;
                losowanieGlobalne = LottoLosowaniaTools.LosowaniaList[iGlobalne];
                for (int iSymetryczne = 0; iSymetryczne < maxSymetryczne; iSymetryczne++)
                {
                    losowanieSymetryczne = symetryczne[iSymetryczne];
                    lCount = 0;
                    for (int i = 0; i < 6; i++)
                    {
                        if (losowanieSymetryczne.Contains(losowanieGlobalne[i]))
                            lCount++;
                        if (lCount == x || (lCount + 4 - i) < x)
                            break;
                    }
                    if (lCount == x)
                    {
                        count++;
                        break;
                    }
                }
                if (count >= y)
                    return true;
                if (count + (maxGlobalne - 1 - iGlobalne) < y)
                    return false;
            }

            return false;
        }

        protected override string EditableColumns
        {
            get { return "XY"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);

            string str = "";
            if (x < 1 || x > 6)
            {
                str = "X powinno być z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscLosowan)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscLosowan;
                SetColError(row, "Y", str);
                return false;
            }
            return true;
        }

        public override bool IsActionForLosowanie
        {
            get
            {
                return true;
            }
        }
    }
    public class ActionLottoPowtorzoneSymetryczneOgraniczone : ActionLottoBase
    {
        public override string Name
        {
            get { return "Conajmniej X liczb lub liczb symetrycznych powtórzyło się w conajmniej Y losowaniach uwzględniając poprzednie Z losowań"; }
        }

        public override string Kod
        {
            get { return "Powtorzone symetryczne ograniczone"; }
        }

        public override string Opis
        {
            get { return "Conajmniej X liczb lub liczb symetrycznych powtórzyło się w conajmniej Y losowaniach uwzględniając poprzednie Z losowań"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int lCount = 0;
            int count = 0;
            
            int numerLosowania = liczby[6];
            if (numerLosowania < y)
                return false;

            int iMin = numerLosowania - z;
            if (iMin < 0)
                iMin = 0;
            List<List<int>> symetryczne = GetSymetryczne(liczby);
            
            int maxGlobalne = numerLosowania;
            int maxSymetryczne = symetryczne.Count;


            List<int> losowanieSymetryczne;
            List<int> losowanieGlobalne;
            for (int iGlobalne = iMin; iGlobalne < maxGlobalne; iGlobalne++)
            {
                losowanieGlobalne = LottoLosowaniaTools.LosowaniaList[iGlobalne];
                for (int iSymetryczne = 0; iSymetryczne < maxSymetryczne; iSymetryczne++)
                {
                    losowanieSymetryczne = symetryczne[iSymetryczne];
                    lCount = 0;
                    for (int i = 0; i < 6; i++)
                    {
                        if (losowanieSymetryczne.Contains(losowanieGlobalne[i]))
                            lCount++;
                        if (lCount == x || (lCount + 4 - i) < x)
                            break;
                    }
                    if (lCount == x)
                    {
                        count++;
                        break;
                    }
                }
                if (count >= y)
                    return true;
                if (count + (maxGlobalne - 1 - iGlobalne) < y)
                    return false;
            }

            return false;
        }

        protected override string EditableColumns
        {
            get { return "XYZ"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (x < 1 || x > 6)
            {
                str = "X powinno być z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscLosowan)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscLosowan;
                SetColError(row, "Y", str);
                return false;
            }
            else if (z < y || z > LottoLosowaniaTools.IloscLosowan)
            {
                str = "Y powinno być z zakresu " + y + " - " + LottoLosowaniaTools.IloscLosowan;
                SetColError(row, "Z", str);
                return false;
            }
            return true;
        }

        public override bool IsActionForLosowanie
        {
            get
            {
                return true;
            }
        }
    }

    public class ActionLottoNajczestsze : ActionLottoBase
    {
        public override string Name
        {
            get { return "Conajmniej X liczb należy do Y najczęściej padających liczb"; }
        }

        public override string Kod
        {
            get { return "Najczestsze liczby"; }
        }

        public override string Opis
        {
            get { return "Conajmniej X liczb należy do Y najczęściej padających liczb"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count=0;
            NajczestszeLiczby globalDwojka;
            for (int j=0; j < 6; j++)
            {
                for (int i=0; i < y; i++)
                {
                    globalDwojka = LottoLosowaniaTools.NajczestszeLiczby[i];

                    if (globalDwojka.Liczby.Contains(liczby[j]))
                        count++;
                    if (count == x)
                        return true;
                }
            }
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XY"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (LottoLosowaniaTools.IloscNajczestszychLiczb == 0)
            {
                str = "Brak informacji o najczestszych liczbach";
                SetColError(row, "Y", str);
                return false;
            }
            else if (x < 1 || x > 6)
            {
                str = "X powinno być z zakresu 1 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscNajczestszychLiczb)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscNajczestszychLiczb;
                SetColError(row, "Y", str);
                return false;
            }
            
            return true;
        }
    }
    public class ActionLottoNajczestsze2 : ActionLottoBase
    {
        public override string Name
        {
            get { return "Nie wiecej niż X liczb należy do Y najczęściej padających liczb"; }
        }

        public override string Kod
        {
            get { return "Najczestsze liczby 2"; }
        }

        public override string Opis
        {
            get { return "Nie wiecej niż X liczb należy do Y najczęściej padających liczb"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count=0;
            NajczestszeLiczby globalDwojka;
            for (int j=0; j < 6; j++)
            {
                for (int i=0; i < y; i++)
                {
                    globalDwojka = LottoLosowaniaTools.NajczestszeLiczby[i];

                    if (globalDwojka.Liczby.Contains(liczby[j]))
                        count++;
                    if (count > x)
                        return false;
                }
            }
            return true;
        }
        protected override string EditableColumns
        {
            get { return "XY"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (LottoLosowaniaTools.IloscNajczestszychLiczb == 0)
            {
                str = "Brak informacji o najczestszych liczbach";
                SetColError(row, "Y", str);
                return false;
            }
            else if (x < 0 || x > 6)
            {
                str = "X powinno być z zakresu 0 - 6";
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscNajczestszychLiczb)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscNajczestszychLiczb;
                SetColError(row, "Y", str);
                return false;
            }

            return true;
        }
    }
    public class ActionLottoNajczestszeDwojki : ActionLottoBase
    {
        private List<List<int>> GetDwojki(List<int> liczby)
        {
            List<List<int>> list = new List<List<int>>();
            for (int l1=0; l1 < 5; l1++)
            {
                for (int l2=l1 + 1; l2 < 6; l2++)
                    list.Add(new List<int>() { liczby[l1], liczby[l2] });
            }
            return list;
        }
        public override string Name
        {
            get { return "Conajmniej X par liczb należy do Y najczęściej padających dwojek"; }
        }

        public override string Kod
        {
            get { return "Najczestsze dwojki"; }
        }

        public override string Opis
        {
            get { return "Conajmniej X par liczb należy do Y najczęściej padających dwojek"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count=0;
            List<List<int>> dwojki = GetDwojki(liczby);
            int dwojkiCount = dwojki.Count;
            NajczestszeLiczby globalDwojka;
            List<int> localDwojka;
            for (int j=0; j < dwojkiCount; j++)
            {
                localDwojka = dwojki[j];
                for (int i=0; i < y; i++)
                {
                    globalDwojka = LottoLosowaniaTools.NajczestszeDwojki[i];

                    if (globalDwojka.Liczby.Contains(localDwojka[0]) &&
                        globalDwojka.Liczby.Contains(localDwojka[1]))
                        count++;
                    if (count == x)
                        return true;
                }
            }
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XY"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (LottoLosowaniaTools.IloscNajczestszychDwojek == 0)
            {
                str = "Brak informacji o najczestszych dwojkach";
                SetColError(row, "Y", str);
                return false;
            }
            else if (x < 1 || x > LottoLosowaniaTools.LICZBA_KOMBINACJI_2_Z_6)
            {
                str = "X powinno być z zakresu 1 - " + LottoLosowaniaTools.LICZBA_KOMBINACJI_2_Z_6;
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscNajczestszychDwojek)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscNajczestszychDwojek;
                SetColError(row, "Y", str);
                return false;
            }

            return true;
        }
    }
    public class ActionLottoNajczestszeDwojki2 : ActionLottoBase
    {
        private List<List<int>> GetDwojki(List<int> liczby)
        {
            List<List<int>> list = new List<List<int>>();
            for (int l1=0; l1 < 5; l1++)
            {
                for (int l2=l1 + 1; l2 < 6; l2++)
                    list.Add(new List<int>() { liczby[l1], liczby[l2] });
            }
            return list;
        }
        public override string Name
        {
            get { return "Nie wiecej niż X par liczb należy do Y najczęściej padających dwojek"; }
        }

        public override string Kod
        {
            get { return "Najczestsze dwojki 2"; }
        }

        public override string Opis
        {
            get { return "Nie wiecej niż X par liczb należy do Y najczęściej padających dwojek"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count=0;
            List<List<int>> dwojki = GetDwojki(liczby);
            int dwojkiCount = dwojki.Count;
            NajczestszeLiczby globalDwojka;
            List<int> localDwojka;
            for (int j=0; j < dwojkiCount; j++)
            {
                localDwojka = dwojki[j];
                for (int i=0; i < y; i++)
                {
                    globalDwojka = LottoLosowaniaTools.NajczestszeDwojki[i];

                    if (globalDwojka.Liczby.Contains(localDwojka[0]) &&
                        globalDwojka.Liczby.Contains(localDwojka[1]))
                        count++;
                    if (count == x)
                        return true;
                }
            }
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XY"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (LottoLosowaniaTools.IloscNajczestszychDwojek == 0)
            {
                str = "Brak informacji o najczestszych dwojkach";
                SetColError(row, "Y", str);
                return false;
            }
            else if (x < 0 || x > LottoLosowaniaTools.LICZBA_KOMBINACJI_2_Z_6)
            {
                str = "X powinno być z zakresu 0 - " + LottoLosowaniaTools.LICZBA_KOMBINACJI_2_Z_6;
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscNajczestszychDwojek)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscNajczestszychDwojek;
                SetColError(row, "Y", str);
                return false;
            }

            return true;
        }
    }
    public class ActionLottoNajczestszeTrojki : ActionLottoBase
    {
        private List<List<int>> GetTrojki(List<int> liczby)
        {
            List<List<int>> list = new List<List<int>>();
            for (int l1=0; l1 < 4; l1++)
            {
                for (int l2=l1 + 1; l2 < 5; l2++)
                {
                    for (int l3=l2 + 1; l3 < 6; l3++)
                    list.Add(new List<int>() { liczby[l1], liczby[l2], liczby[l3] });
                }
            }
            return list;
        }
        public override string Name
        {
            get { return "Conajmniej X trójek liczb należy do Y najczęściej padających trójek"; }
        }

        public override string Kod
        {
            get { return "Najczestsze trójki"; }
        }

        public override string Opis
        {
            get { return "Conajmniej X par trójek należy do Y najczęściej padających trójek"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count=0;
            List<List<int>> trojki = GetTrojki(liczby);
            int dwojkiCount = trojki.Count;
            NajczestszeLiczby globalTrojka;
            List<int> localTrojka;
            for (int j=0; j < dwojkiCount; j++)
            {
                localTrojka = trojki[j];
                for (int i=0; i < y; i++)
                {
                    globalTrojka = LottoLosowaniaTools.NajczestszeTrojki[i];

                    if (globalTrojka.Liczby.Contains(localTrojka[0]) &&
                        globalTrojka.Liczby.Contains(localTrojka[1]) &&
                        globalTrojka.Liczby.Contains(localTrojka[2]))
                        count++;
                    if (count == x)
                        return true;
                }
            }
            return false;
        }

        protected override string EditableColumns
        {
            get { return "XY"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (LottoLosowaniaTools.IloscNajczestszychTrojek == 0)
            {
                str = "Brak informacji o najczestszych trojkach";
                SetColError(row, "Y", str);
                return false;
            }
            else if (x < 1 || x > LottoLosowaniaTools.LICZBA_KOMBINACJI_3_Z_6)
            {
                str = "X powinno być z zakresu 1 - " + LottoLosowaniaTools.LICZBA_KOMBINACJI_3_Z_6;
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscNajczestszychTrojek)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscNajczestszychTrojek;
                SetColError(row, "Y", str);
                return false;
            }

            return true;
        }
    }
    public class ActionLottoNajczestszeTrojki2 : ActionLottoBase
    {
        private List<List<int>> GetTrojki(List<int> liczby)
        {
            List<List<int>> list = new List<List<int>>();
            for (int l1=0; l1 < 4; l1++)
            {
                for (int l2=l1 + 1; l2 < 5; l2++)
                {
                    for (int l3=l2 + 1; l3 < 6; l3++)
                        list.Add(new List<int>() { liczby[l1], liczby[l2], liczby[l3] });
                }
            }
            return list;
        }
        public override string Name
        {
            get { return "Nie więcej niż X trójek liczb należy do Y najczęściej padających trójek"; }
        }

        public override string Kod
        {
            get { return "Najczestsze trójki 2"; }
        }

        public override string Opis
        {
            get { return "Nie więcej niż X par trójek należy do Y najczęściej padających trójek"; }
        }

        public override bool LiczbySpelniajaWarunki(List<int> liczby, int x, int y, int z)
        {
            int count=0;
            List<List<int>> trojki = GetTrojki(liczby);
            int dwojkiCount = trojki.Count;
            NajczestszeLiczby globalTrojka;
            List<int> localTrojka;
            for (int j=0; j < dwojkiCount; j++)
            {
                localTrojka = trojki[j];
                for (int i=0; i < y; i++)
                {
                    globalTrojka = LottoLosowaniaTools.NajczestszeTrojki[i];

                    if (globalTrojka.Liczby.Contains(localTrojka[0]) &&
                        globalTrojka.Liczby.Contains(localTrojka[1]) &&
                        globalTrojka.Liczby.Contains(localTrojka[2]))
                        count++;
                    if (count > x)
                        return false;
                }
            }
            return true;
        }

        protected override string EditableColumns
        {
            get { return "XY"; }
        }

        public override bool ValidateParams(DataRow row)
        {
            int x = GetColval(row, "X").AsInt(-1);
            int y = GetColval(row, "Y").AsInt(-1);
            int z = GetColval(row, "Z").AsInt(-1);

            string str = "";
            if (LottoLosowaniaTools.IloscNajczestszychTrojek == 0)
            {
                str = "Brak informacji o najczestszych trojkach";
                SetColError(row, "Y", str);
                return false;
            }
            else if (x < 0 || x > LottoLosowaniaTools.LICZBA_KOMBINACJI_3_Z_6)
            {
                str = "X powinno być z zakresu 0 - " + LottoLosowaniaTools.LICZBA_KOMBINACJI_3_Z_6;
                SetColError(row, "X", str);
                return false;
            }
            else if (y < 1 || y > LottoLosowaniaTools.IloscNajczestszychTrojek)
            {
                str = "Y powinno być z zakresu 1 - " + LottoLosowaniaTools.IloscNajczestszychTrojek;
                SetColError(row, "Y", str);
                return false;
            }

            return true;
        }
    }
    #endregion

}
